/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/********************************************************************************************************
 * \file     Mcal_Scr.c                                                                                 *
 * \brief    AUTOSAR 4.3.1 MCAL MCALLib System Control Driver                                        *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2024/11/20     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif
/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "RegHelper.h"
#include "Mcal_ScrReg.h"
#include "Mcal_Scr.h"
#include "__regs_base.h"
#include "SchM_McalLib.h"
#ifdef CFG_EN_FUSALIB
#include "FSMR_Monitor.h"
#include "FuSaLib_MonitorConfig.h"
#endif /* #ifdef CFG_EN_FUSALIB */
/********************************************************************************************************
 *                                 Imported Compiler Switch Checks                                      *
 *******************************************************************************************************/
/* Version and Check Begin */
/* Version Info Begin */
#define MCAL_SCR_C_VENDOR_ID    0x8C
#define MCAL_SCR_C_AR_RELEASE_MAJOR_VERSION    4
#define MCAL_SCR_C_AR_RELEASE_MINOR_VERSION    3
#define MCAL_SCR_C_AR_RELEASE_REVISION_VERSION 1
#define MCAL_SCR_C_SW_MAJOR_VERSION    1
#define MCAL_SCR_C_SW_MINOR_VERSION    0
#define MCAL_SCR_C_SW_PATCH_VERSION    0
/* Version Info End */

/* Version Check Begin */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((MCAL_SCR_C_AR_RELEASE_MAJOR_VERSION != SCR_REG_H_AR_RELEASE_MAJOR_VERSION)\
    || (MCAL_SCR_C_AR_RELEASE_MINOR_VERSION != SCR_REG_H_AR_RELEASE_MINOR_VERSION)\
    || (MCAL_SCR_C_AR_RELEASE_REVISION_VERSION != SCR_REG_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Mcal_Scr.c and Scr_Reg.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((MCAL_SCR_C_SW_MAJOR_VERSION != SCR_REG_H_SW_MAJOR_VERSION)\
    || (MCAL_SCR_C_SW_MINOR_VERSION != SCR_REG_H_SW_MINOR_VERSION)\
    || (MCAL_SCR_C_SW_PATCH_VERSION != SCR_REG_H_SW_PATCH_VERSION))
#error "Opps, Mcal_Scr.c and Scr_Reg.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
#if !defined(DISABLE_MCAL_ASR_VER_CHECK)
#if ((MCAL_SCR_C_AR_RELEASE_MAJOR_VERSION != MCAL_SCR_H_AR_RELEASE_MAJOR_VERSION)\
    || (MCAL_SCR_C_AR_RELEASE_MINOR_VERSION != MCAL_SCR_H_AR_RELEASE_MINOR_VERSION)\
    || (MCAL_SCR_C_AR_RELEASE_REVISION_VERSION != MCAL_SCR_H_AR_RELEASE_REVISION_VERSION))
#error "Opps, Mcal_Scr.c and Mcal_Scr.h AutoSAR version not match!"
#endif
#endif  /* !DISABLE_MCAL_ASR_VER_CHECK */
#if !defined(DISABLE_MCAL_SW_VER_CHECK)
#if ((MCAL_SCR_C_SW_MAJOR_VERSION != MCAL_SCR_H_SW_MAJOR_VERSION)\
    || (MCAL_SCR_C_SW_MINOR_VERSION != MCAL_SCR_H_SW_MINOR_VERSION)\
    || (MCAL_SCR_C_SW_PATCH_VERSION != MCAL_SCR_H_SW_PATCH_VERSION))
#error "Opps, Mcal_Scr.c and Mcal_Scr.h Software version not match!"
#endif
#endif  /* !DISABLE_MCAL_SW_VER_CHECK */
/* Version Check End */
/* Version and Check End */
/********************************************************************************************************
 *                                 Global Macro definition                                              *
 *******************************************************************************************************/
/** \brief  Scr P/N check */
#define MCALLIB_SCR_RO_N_START_BIT 16U
#define MCALLIB_SCR_BIT_MASK(x) (((x) >= (sizeof(uint32) * 8U)) ? (0xFFFFFFFFU) : ((1UL << (x)) - 1UL))
/********************************************************************************************************
 *                                  Global Constant Declarations                                        *
 *******************************************************************************************************/
#define MCALLIB_START_SEC_CONST_UNSPECIFIED
#include "McalLib_MemMap.h"

/* scr device *//* PRQA S 1514, 3408 4 */
const Mcal_ScrDevType Mcal_GlobalScrSF =
{
    .base = APB_SCR_SAETY_BOOT_BASE,
    .regShift = 0U,
    .regOffset = {
        [TYPE_RW] = 0x1000U,
        [TYPE_RO] = 0x1300U,
        [TYPE_L16] = 0x1600U,
        [TYPE_L31] = 0x1900U,
        [TYPE_R16W16] = 0x1C00U,
    },
};
/* scr device *//* PRQA S 1514, 3408 4 */
const Mcal_ScrDevType Mcal_GlobalScrLP =
{
    .base = APB_SCR_LP_BASE,
    .regShift = 0U,
    .regOffset = {
        [TYPE_RW] = 0x1000U,
        [TYPE_RO] = 0x1300U,
        [TYPE_L16] = 0x1600U,
        [TYPE_L31] = 0x1900U,
        [TYPE_R16W16] = 0x1C00U,
    },
};

#define MCALLIB_STOP_SEC_CONST_UNSPECIFIED
#include "McalLib_MemMap.h"
/********************************************************************************************************
 *                                  Private Function Declarations                                       *
 *******************************************************************************************************/
MCALLIB_LOCAL_INLINE const Mcal_ScrDevType *Mcal_Ip_ScrGetDevice(const Mcal_ScrSignalType *scrSignal);
MCALLIB_LOCAL_INLINE uint32 Mcal_Ip_ScrReg(const Mcal_ScrSignalType *scrSignal);
MCALLIB_LOCAL_INLINE uint32 Mcal_Ip_ScrReadReg(const Mcal_ScrSignalType *scrSignal);
MCALLIB_LOCAL_INLINE void Mcal_Ip_ScrWriteReg(const Mcal_ScrSignalType *scrSignal, uint32 val);
MCALLIB_LOCAL boolean Mcal_Ip_ScrIsLocked(const Mcal_ScrSignalType *scrSignal);
MCALLIB_LOCAL Std_ReturnType Mcal_Ip_ScrSetBit(const Mcal_ScrSignalType *scrSignal, uint32 value);
MCALLIB_LOCAL boolean Mcal_Ip_ScrLock(const Mcal_ScrSignalType *scrSignal);

#define MCALLIB_START_SEC_CODE
#include "McalLib_MemMap.h"
/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * \brief This function to get scr bit value of this signal.
 *
 * \verbatim
 * Syntax             : Mcal_ScrGetBit
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - The system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The bit value of this signal.
 *
 * Description        : This function to get scr bit value of this signal.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
uint32 Mcal_ScrGetBit(const Mcal_ScrSignalType *scrSignal)
{
    /* ----- Local Variables ---------------------------------------------- */
    uint32 scrValue = UINT32_MAX;
    uint32 regValue;
    uint32 startBit;
    uint32 valueCheck;

    if (NULL_PTR != scrSignal)
    {
        regValue = Mcal_Ip_ScrReadReg(scrSignal);
        /*PRQA S 4491 1*/
        startBit = scrSignal->startBit & SCR_BITFIELD_POS_MSK;
        scrValue = (regValue >> startBit) & MCALLIB_SCR_BIT_MASK(scrSignal->width);

        if (TYPE_RO == scrSignal->type)
        {
            valueCheck = ((~regValue) >> (startBit + MCALLIB_SCR_RO_N_START_BIT)) &
                         MCALLIB_SCR_BIT_MASK(scrSignal->width);

            if (scrValue != valueCheck)
            {
#ifdef CFG_EN_FUSALIB
                /* triggr sem error */
                FuSaLib_MonitorTrigInt(SEM_OUTPUT_CPU, FUSALIB_MON_TRIG_INT_ERROR_TYPE_SCR_PN_CHECK, TRUE);
#endif /* #ifdef CFG_EN_FUSALIB */
            }
        }
    }

    return scrValue;
}
/** *****************************************************************************************************
 * \brief This function to set scr bit value of this signal.
 *
 * \verbatim
 * Syntax             : Mcal_ScrSetBit
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - The system control register signal.
 *                      value - The value will be set to this scr.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The bit value of this signal.
 *
 * Description        : This function to set scr bit value of this signal.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
Std_ReturnType Mcal_ScrSetBit(const Mcal_ScrSignalType *scrSignal, uint32 value)
{
    Std_ReturnType errorId;

    if (NULL_PTR == scrSignal)
    {
        errorId = MCALLIB_E_PARAM_POINTER;
    }
    else
    {
        errorId = Mcal_Ip_ScrSetBit(scrSignal, value);
    }

    return errorId;
}
/** *****************************************************************************************************
 * \brief This function to lock scr of this signal.
 *
 * \verbatim
 * Syntax             : Mcal_ScrLock
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - The system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE: This scr is locked.
 *                      FALSE: This scr doesn't need to be locked.
 *
 * Description        : This function to lock scr of this signal.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
Std_ReturnType Mcal_ScrLock(const Mcal_ScrSignalType *scrSignal)
{
    /* ----- Local Variables ---------------------------------------------- */
    Std_ReturnType errorId;
    boolean ret;

    if (NULL_PTR == scrSignal)
    {
        errorId = MCALLIB_E_PARAM_POINTER;
    }
    else
    {
        ret = Mcal_Ip_ScrLock(scrSignal);

        if (ret == TRUE)
        {
            errorId = E_OK;
        }
        else
        {
            errorId = MCALLIB_E_SCR_NO_NEED_LOCK;
        }
    }

    return errorId;
}
/** *****************************************************************************************************
 * \brief This function to get if locked of this scr.
 *
 * \verbatim
 * Syntax             : Mcal_ScrIsLocked
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - the system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE: This scr is locked.
 *                      FALSE: This scr is unlocked.
 *
 * Description        : This function to get if locked of this scr.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
boolean Mcal_ScrIsLocked(const Mcal_ScrSignalType *scrSignal)
{
    boolean ret = FALSE;

    if (NULL_PTR != scrSignal)
    {
        ret = Mcal_Ip_ScrIsLocked(scrSignal);
    }

    return ret;
}
/** *****************************************************************************************************
 * \brief This function returns the device of this signal.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrGetDevice
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - the system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The device of this signal.
 *
 * Description        : This function returns the device of this signal.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL_INLINE const Mcal_ScrDevType *Mcal_Ip_ScrGetDevice(const Mcal_ScrSignalType *scrSignal)
{
    Mcal_ScrDevType const *dev;

    if (SF_DOMAIN == scrSignal->domain)
    {
        dev = &Mcal_GlobalScrSF;
    }
    else
    {
        dev = &Mcal_GlobalScrLP;
    }

    return dev;
}
/** *****************************************************************************************************
 * \brief This function returns the register base address of this signal.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrReg
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - the system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The register base address of this signal.
 *
 * Description        : This function returns the register base address of this signal.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL_INLINE uint32 Mcal_Ip_ScrReg(const Mcal_ScrSignalType *scrSignal)
{
    const Mcal_ScrDevType *dev = Mcal_Ip_ScrGetDevice(scrSignal);
    /*PRQA S 1891 1*/
    uint32 regOffset = dev->regOffset[scrSignal->type] + ((scrSignal->startBit >> 5U) * 4U);
    return dev->base + (regOffset << dev->regShift);
}
/** *****************************************************************************************************
 * \brief This function to get scr value of this signal from register.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrReadReg
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - the system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : The value of this scr register.
 *
 * Description        : This function to get scr value of this signal from register.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL_INLINE uint32 Mcal_Ip_ScrReadReg(const Mcal_ScrSignalType *scrSignal)
{
    return REG_READ32(Mcal_Ip_ScrReg(scrSignal));
}
/** *****************************************************************************************************
 * \brief This function to write scr value of this signal to register.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrWriteReg
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - the system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function to write scr value of this signal to register.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL_INLINE void Mcal_Ip_ScrWriteReg(const Mcal_ScrSignalType *scrSignal, uint32 val)
{
    REG_WRITE32(val, Mcal_Ip_ScrReg(scrSignal));
}
/** *****************************************************************************************************
 * \brief This function to get if locked of this scr.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrIsLocked
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - the system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE: This scr is locked.
 *                      FALSE: This scr is unlocked.
 *
 * Description        : This function to get if locked of this scr.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL boolean Mcal_Ip_ScrIsLocked(const Mcal_ScrSignalType *scrSignal)
{
    uint32 val = Mcal_Ip_ScrReadReg(scrSignal);
    boolean locked;
    /*PRQA S 4491 1*/
    uint32 startBit = scrSignal->startBit & SCR_BITFIELD_POS_MSK;

    switch (scrSignal->type)
    {
    case TYPE_L16:
        if (startBit < 16U)
        {
            locked = (boolean)((val & (1UL << (startBit + 16U))) >> (startBit + 16U));
        }
        else
        {
            locked = (boolean)((val & (1UL << startBit)) >> startBit);
        }
        break;

    case TYPE_L31:
        locked = (boolean)((val & (1UL << 31U)) >> 31U);
        break;

    case TYPE_R16W16:
        locked = (startBit >= 16U) ? TRUE : FALSE;
        break;

    /* Read only bits are considered locked.*/
    case TYPE_RO:
        locked = TRUE;
        break;

    case TYPE_RW:
    default:
        locked = FALSE;
        break;
    }

    return locked;
}
/** *****************************************************************************************************
 * \brief This function to set scr bit value of this signal to register.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrSetBit
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - The system control register signal.
 *                      value - The value will be set to this scr register.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : E_OK: This bit of scr is set successfully.
 *                      MCALLIB_E_SCR_LOCK: Scr register of this signal is lock.
 *
 * Description        : This function to set scr bit value of this signal to register.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL Std_ReturnType Mcal_Ip_ScrSetBit(const Mcal_ScrSignalType *scrSignal, uint32 value)
{
    uint32 val;
    /*PRQA S 4491 1*/
    uint32 startBit = scrSignal->startBit & SCR_BITFIELD_POS_MSK;
    Std_ReturnType errorId;

    if (Mcal_Ip_ScrIsLocked(scrSignal) == TRUE)
    {
        errorId = MCALLIB_E_SCR_LOCK;
    }
    else
    {
        SchM_Enter_McalLib_MCALLIB_EXCLUSIVE_AREA_00();
        val = Mcal_Ip_ScrReadReg(scrSignal);
        val &= ~(MCALLIB_SCR_BIT_MASK(scrSignal->width) << startBit);
        val |= value << startBit;
        Mcal_Ip_ScrWriteReg(scrSignal, val);
        errorId = E_OK;
        SchM_Exit_McalLib_MCALLIB_EXCLUSIVE_AREA_00();
    }

    return errorId;
}
/** *****************************************************************************************************
 * \brief This function to lock scr of this signal.
 *
 * \verbatim
 * Syntax             : Mcal_Ip_ScrLock
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Reentrant
 *
 * Parameters (in)    : scrSignal - The system control register signal.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : TRUE: This scr is locked.
 *                      FALSE: This scr doesn't need to be locked.
 *
 * Description        : This function to lock scr of this signal.
 * \endverbatim
 * Traceability       :
 *******************************************************************************************************/
MCALLIB_LOCAL_INLINE boolean Mcal_Ip_ScrLock(const Mcal_ScrSignalType *scrSignal)
{
    uint32 val;
    boolean ret;
    /*PRQA S 4491 1*/
    uint32 startBit = scrSignal->startBit & SCR_BITFIELD_POS_MSK;

    if (Mcal_Ip_ScrIsLocked(scrSignal) == TRUE)
    {
        ret = TRUE;
    }
    else
    {
        switch (scrSignal->type)
        {
        case TYPE_L16:
            SchM_Enter_McalLib_MCALLIB_EXCLUSIVE_AREA_00();
            val = Mcal_Ip_ScrReadReg(scrSignal);
            if (startBit < 16U)
            {
                val |= MCALLIB_SCR_BIT_MASK(scrSignal->width) << (startBit + 16U);
            }
            else /* sticky bit */
            {
                val |= MCALLIB_SCR_BIT_MASK(scrSignal->width) << startBit;
            }

            Mcal_Ip_ScrWriteReg(scrSignal, val);
            ret = TRUE;
            SchM_Exit_McalLib_MCALLIB_EXCLUSIVE_AREA_00();
            break;

        case TYPE_L31:
            SchM_Enter_McalLib_MCALLIB_EXCLUSIVE_AREA_00();
            val = Mcal_Ip_ScrReadReg(scrSignal);
            val |= 1UL << 31U;
            Mcal_Ip_ScrWriteReg(scrSignal, val);
            ret = TRUE;
            SchM_Exit_McalLib_MCALLIB_EXCLUSIVE_AREA_00();
            break;

        case TYPE_R16W16:
        case TYPE_RW:
        case TYPE_RO:
        default:
            ret = FALSE;
            break;
        }
    }

    return ret;
}
#define MCALLIB_STOP_SEC_CODE
#include "McalLib_MemMap.h"

#ifdef __cplusplus
}
#endif
/* End of file */
